在早期的 JavaScript 開發中, 命名空間污染 是一個重大障礙。當不相關的程式碼共享同一組全域變數名稱時,會發生無法預測的衝突。現代設計已從無結構的態度轉向 隔離的模組系統。
1. 功能性隔離(立即執行函式表達式)
透過將程式碼包裝在一個 立即執行函式表達式 (IIFE)中,我們創造出一個私有作用域。像 names 這樣的變數被鎖在函式內部,無法存取全域環境。
(function() {
var internal = "secret";
console.log(internal);
})();
var internal = "secret";
console.log(internal);
})();
2. 基於物件的介面
為了讓外部世界能使用功能,模組會回傳一個物件,作為其 公開介面。這將相關的方法(例如 name 和 number)整合到單一重新取得的全域變數之下。
3. 匯出模式
一種進階的變化是將一個 exports 物件傳遞至 IIFE。這讓模組能直接將其 API 附加至特定命名空間目標,提供模組被使用的彈性。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is 'Namespace Pollution' in the context of JavaScript?
Using too many comments in the source code.
Unrelated code having to share a single set of global variable names.
A failure in the garbage collection system.
The inability to use numbers as variable identifiers.
✅ Correct!
Namespace pollution makes code fragile because any script might overwrite global variables used by another.❌ Incorrect
It refers specifically to the overcrowding and conflict of names in the global scope.QUESTION 2
Why is an IIFE used to create a module?
To make the code run faster in the browser.
To bypass the 'use strict' requirement.
To create an isolated, private namespace via function scope.
To automatically export variables to the window object.
✅ Correct!
Functions are the primary way in JavaScript to create a new scope that hides internal logic from the outside.❌ Incorrect
IIFEs provide encapsulation, preventing internal variables from leaking into the global scope.QUESTION 3
In the 'weekDay' module example, what allows the returned functions to access the 'names' array?
The 'names' array is actually a global variable.
JavaScript Closures.
The 'this' keyword refers to the array.
The array is passed as an argument to each function.
✅ Correct!
Closures allow nested functions to remember and access the variables in their outer function's scope.❌ Incorrect
It is the mechanism of closures that keeps the local 'names' variable alive for the interface methods.QUESTION 4
What is the primary purpose of returning an object from a module function?
To save memory by grouping variables.
To provide a structured public interface for the module.
To convert the script into an asynchronous process.
To ensure the code is compatible with Internet Explorer.
✅ Correct!
The object acts as a gateway, exposing only the intended methods while keeping others hidden.❌ Incorrect
The object serves as the 'Interface' mentioned in the learning outcomes.QUESTION 5
What is passed as an argument in the Exports Pattern: `(function(exports) { ... })(this.weekDay = {});`?
The entire window object.
An empty string.
A reference to a new object assigned to weekDay.
A list of dependency names.
✅ Correct!
This pattern explicitly creates a target object and passes it in to be 'filled' with functionality.❌ Incorrect
It passes a specific object that will hold the module's public API.Case Study: Manual Module Construction
Building a Month Converter Module
You need to create a utility that handles month data without polluting the global namespace. The utility must convert zero-based month numbers (0-11) to strings and vice-versa. It should use plain JavaScript without external loaders.
Q
Write a simple module similar to the weekday module that can convert month numbers (zero-based) to names and convert names back to numbers. Give it its own namespace and use an internal array.
Solution:
var month = (function() { var names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; return { name: function(number) { return names[number]; }, number: function(name) { return names.indexOf(name); } }; })(); // Usage example: console.log(month.name(2)); // 'March' console.log(month.number("November")); // 10
var month = (function() { var names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; return { name: function(number) { return names[number]; }, number: function(name) { return names.indexOf(name); } }; })(); // Usage example: console.log(month.name(2)); // 'March' console.log(month.number("November")); // 10
Q
How does this implementation protect the 'names' array from external modification?
Solution:
The 'names' array is declared with 'var' inside the IIFE function scope. Because it is not part of the returned object, it is not accessible from the global scope. Only the functions 'name' and 'number' have access to it through closure.
The 'names' array is declared with 'var' inside the IIFE function scope. Because it is not part of the returned object, it is not accessible from the global scope. Only the functions 'name' and 'number' have access to it through closure.